<?php
namespace app\goods\service;
use app\common\library\Service;

class GoodsOrder extends Service
{

    use \app\common\library\traits\Model;

    protected $model;
    protected function _initialize()
    {
        parent::_initialize();
        $this->model = model('goods/goods_order');
    }

    /**
     * 创建兑换订单
     * @param int $goods_id     商品ID
     * @param int $user_id      用户ID
     * @param array $delivery   收货信息
     * @param int $number       兑换数量
     * @return boolean
     */
    public function create($goods_id, $user_id, $delivery = [], $number = 1) {
        $goods_id = (int) $goods_id;
        $user_id = (int) $user_id;
        $delivery = (array) $delivery;
        $number = (int) $number;

        $user = model('user/user', 'service')->where(['id' => $user_id])->find();
        if(!$user) {
            $this->error = "用户信息异常";
            return false;
        }

        if($user['status'] != 1) {
            $this->error = "用户状态异常";
            return false;
        }

        $goods = model('goods/goods', 'service')->find($goods_id);
        if(!$goods || $goods['status'] != 1) {
            $this->error = "商品状态异常";
            return false;
        }

        if($goods['type'] == 0) {
            if(!$delivery['realname'] || !$delivery['mobile'] || !$delivery['address']) {
                $this->error = "收货信息为必填项";
                return false;
            }
        }

        if($goods['use_customer'] == 0 && $user['role'] == 2) {
            $this->error = "不支持客户经理兑换";
            return false;
        }

        if($user['point'] < $goods['point']) {
            $this->error = "您的积分不足";
            return false;
        }

        if($goods['stock'] < $number) {
            $this->error = "商品库存不足";
            return false;
        }


        $order_no = 'G'.date('YmdHis').\fast\Random::build('numeric', 6);
        $info = [
            'order_no' => (string) $order_no,
            'uid' => (int) $user_id,
            'nickname' => (string) $user['nickname'],
            'goods_id' => (int) $goods_id,
            'goods_title' => (string)$goods['title'],
            'goods_type' => (int) $goods['type'],
            'number' => (int) $number,
            'points' => (int) $goods['point'],
            'address' => (string) $delivery['address'],
            'mobile' => (string) $delivery['mobile'],
            'realname' => (string) $delivery['realname'],
        ];


        // 兼容虚拟商品
        if($goods['type'] == 1) {
            if(!$goods->stock_info) {
                $this->error = '库存批次异常';
                return false;
            }
            if(!$goods->stock_info->GoodsOrderCreateInfo) {
                $this->error = '库存批次异常';
                return false;
            }
            $info['stock_id'] = (int) $goods->stock_info->id;
            $info['stock_attrs'] = $goods->stock_info->attrs;
            $info['stock_ticket_id'] = $goods->stock_info->GoodsOrderCreateInfo->id;
            $info['status'] = 1;
            $info['stage'] = 2;
            $info['confrim_time'] = time();
            $info['delivery_time'] = time();
        }


        \think\Db::startTrans();
        $result = $this->save($info);
        if(!$result) {
            \think\Db::rollback();
            $this->error = $this->getError();
            return false;
        }
        // 写入订单跟踪
        $trace = model('goods/goods_order_trace', 'service')->create('create', $result);
        if(!$trace) {
            \think\Db::rollback();
            $this->error = model('goods/goods_order_trace', 'service')->getError();
            return false;
        }
        model('goods/goods_order_trace', 'service')->create('confrim', $result);
        model('goods/goods_order_trace', 'service')->create('delivery', $result);
        // 扣除用户积分
        $user_point = model('user/user', 'service')->point($user_id, -$goods['point'], 'goods', '兑换扣除积分 - '.$goods['title'], $order_no);
        if(!$user_point) {
            \think\Db::rollback();
            $this->error = model('user/user', 'service')->getError();
            return false;
        }
        // 更新兑换次数
        $user_goods_num = model('user/user')->where('id', '=', $user_id)->setInc('goods_num');
        if(!$user_goods_num) {
            \think\Db::rollback();
            $this->error = '系统异常';
            return false;
        }

        \think\Hook::listen('GoodsOrderCreateAfter', $result);
        \think\Db::commit();
        return $result;
    }

    /**
     * 订单确认
     * @param $order_no
     * @return mixed
     */
    public function confrim($order_no) {
        $order = $this->model->where(['order_no' => $order_no])->find();
        if(!$order || $order['status'] !== 0) {
            $this->error = "订单状态异常";
            return false;
        }

        if($order['stage'] !== 0) {
            $this->error = "该订单无需确认";
            return false;
        }

        $order->stage = 1;
        $order->confrim_time = time();

        \think\Db::startTrans();
        $result = $order->save();
        if(!$result) {
            \think\Db::rollback();
            return false;
        }

        $trace = model('goods/goods_order_trace', 'service')->create('confrim', $order);
        if(!$trace) {
            \think\Db::rollback();
            $this->error = model('goods/goods_order_trace', 'service')->getError();
            return false;
        }
        \think\Hook::listen('goods_order_confrim_after', $order);
        \think\Db::commit();
        return $order;
    }

    /**
     * 订单发货
     * @param string $order_no
     * @param string $delivery_code
     * @param string $delivery_sn
     * @param bool $force
     * @return bool
     */
    public function delivery($order_no, $delivery_code,  $delivery_sn, $force = false) {
        $order = $this->model->where(['order_no' => $order_no])->find();
        if(!$order || $order['status'] !== 0) {
            $this->error = "订单状态异常";
            return false;
        }
        if($order['stage'] !== 1 && $force === false) {
            $this->error = "该订单无需发货";
        }

        if(!$delivery_sn || !$delivery_code) {
            $this->error = "物流单号或编码不能为空";
            return false;
        }

        $deliverys = config('goods.deliverys');

        $order['delivery_sn'] = $delivery_sn;
        $order['delivery_code'] = $delivery_code;
        $order['delivery_name'] = $deliverys[$delivery_code];
        $order['delivery_time'] = time();
        $order['stage'] = 2;

        \think\Db::startTrans();
        $result = $order->save();
        if(!$result) {
            \think\Db::rollback();
            return false;
        }
        $trace = model('goods/goods_order_trace', 'service')->create('delivery', $order);
        if(!$trace) {
            \think\Db::rollback();
            $this->error = model('goods/goods_order_trace', 'service')->getError();
            return false;
        }

        \think\Hook::listen('goods_order_delivery_after', $order);
        \think\Db::commit();
        return $order;
    }

    /**
     * 订单完成
     */
    public function finish($order_no) {
        $order = $this->model->where(['order_no' => $order_no])->find();
        if(!$order || $order['status'] !== 0) {
            $this->error = "订单状态异常";
            return false;
        }
        $order['status'] = 1;
        $order['stage'] = 99;
        $order['finsh_time'] = time();
        $result = $order->save();
        if(!$result) {
            \think\Db::rollback();
            $this->error = $order->getError();
            return false;
        }

        $trace = model('goods/goods_order_trace', 'service')->create('finish', $order);
        if(!$trace) {
            \think\Db::rollback();
            $this->error = model('goods/goods_order_trace', 'service')->getError();
            return false;
        }

        \think\Hook::listen('goods_order_delivery_after', $order);
        \think\Db::commit();
        return $order;


    }


    /**
     * 订单取消
     * @param $order_no
     * @param bool $force
     * @return bool
     */
    public function cancel($order_no, $force = false) {
        $order = $this->model->where(['order_no' => $order_no])->find();
        if(!$order || $order['status'] !== 0) {
            $this->error = "订单状态异常";
            return false;
        }

        if($order['status'] == -1 && $force !== false) {
            $this->error = "订单状态异常";
            return false;
        }

        $order['cancel_time'] = time();
        $order['status'] = -1;
        $order['stage'] = -1;

        \think\Db::startTrans();
        $result = $order->save();
        if(!$result) {
            \think\Db::rollback();
            return false;
        }

        $trace = model('goods/goods_order_trace', 'service')->create('cancel', $order);
        if(!$trace) {
            \think\Db::rollback();
            $this->error = model('goods/goods_order_trace', 'service')->getError();
            return false;
        }

        \think\Hook::listen('goods_order_cancel_after', $order);
        \think\Db::commit();
        return $order;
    }

}
